﻿using FlyingEye.Come;
using FlyingEye.Come.Repositories;
using FlyingEye.Consts;
using FlyingEye.DeviceMaintenance;
using FlyingEye.DeviceMaintenance.Repositories;
using FlyingEye.Factories;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Guids;
using Volo.Abp.Uow;

namespace FlyingEye.DeviceOpsService
{
    /// <summary>
    /// 数据种子构造器
    /// </summary>
    public class DeviceOpsServiceDataSeedContributor : IDataSeedContributor, ITransientDependency
    {
        private readonly IGuidGenerator _guidGenerator;

        private readonly IDeviceMaintenanceRepository _deviceMaintenanceRepository;

        private readonly IDevicePartRepository _devicePartRepository;

        private readonly IDevicePartCheckItemRepository _devicePartCheckItemRepository;

        private readonly IMaintenanceRecordRepository _maintenanceRecordRepository;

        private readonly IDevicePartCheckedResultRepository _devicePartCheckedResultRepository;

        private readonly IComeUserNotificationConfigurationRepository _comeUserNotificationConfigurationRepository;

        private readonly IComeGroupNotificationConfigurationRepository _comeGroupNotificationConfigurationRepository;

        private readonly IComeUserRepository _comeUserRepository;

        private readonly IMaintenanceMemberRepository _maintenanceMemberRepository;

        private readonly IProductionBaseRepository _productionBaseRepository;

        private readonly IProductionWorkshopRepository _productionWorkshopRepository;

        private readonly IDeviceHostRepository _deviceHostRepository;

        private readonly IProductionProcessRepository _productionProcessRepository;

        private readonly IDevicePartCharacteristicRepository _devicePartCharacteristicRepository;

        public DeviceOpsServiceDataSeedContributor(
            IGuidGenerator guidGenerator,
            IDeviceMaintenanceRepository deviceMaintenanceRepository,
            IDevicePartRepository devicePartRepository,
            IDevicePartCheckItemRepository devicePartCheckItemRepository,
            IMaintenanceRecordRepository maintenanceRecordRepository,
            IDevicePartCheckedResultRepository devicePartCheckedResultRepository,
            IComeUserNotificationConfigurationRepository comeUserNotificationConfigurationRepository,
            IComeGroupNotificationConfigurationRepository comeGroupNotificationConfigurationRepository,
            IComeUserRepository comeUserRepository,
            IMaintenanceMemberRepository maintenanceMemberRepository,
            IProductionWorkshopRepository factoryBaseRepository,
            IDeviceHostRepository deviceHostRepository,
            IProductionProcessRepository productionProcessRepository,
            IProductionBaseRepository productionBaseRepository,
            IDevicePartCharacteristicRepository devicePartCharacteristicRepository)
        {
            _guidGenerator = guidGenerator;
            _deviceMaintenanceRepository = deviceMaintenanceRepository;
            _devicePartRepository = devicePartRepository;
            _devicePartCheckItemRepository = devicePartCheckItemRepository;
            _maintenanceRecordRepository = maintenanceRecordRepository;
            _devicePartCheckedResultRepository = devicePartCheckedResultRepository;
            _comeUserNotificationConfigurationRepository = comeUserNotificationConfigurationRepository;
            _comeGroupNotificationConfigurationRepository = comeGroupNotificationConfigurationRepository;
            _comeUserRepository = comeUserRepository;
            _maintenanceMemberRepository = maintenanceMemberRepository;
            _productionWorkshopRepository = factoryBaseRepository;
            _deviceHostRepository = deviceHostRepository;
            _productionProcessRepository = productionProcessRepository;
            _productionBaseRepository = productionBaseRepository;
            _devicePartCharacteristicRepository = devicePartCharacteristicRepository;
        }

        [UnitOfWork]
        public async Task SeedAsync(DataSeedContext context)
        {
            var userConfiguration = await CreateComeUserNotificationConfigurationAsync();
            var groupConfiguration = await CreateComeGroupNotificationConfigurationAsync();
            var user = await CreateComeUserAsync();

            var productionBase = await CrateProductionBaseAsync();
            var productionWorkshop = await CreateProductionWorkshopAsync(productionBase.Id);
            var productionProcess = await CreateProductionProcessAsync(productionWorkshop.Id);
            var deviceHost = await CreateDeviceHostAsync(productionProcess.Id);

            var project = await CreateProjectAsync(deviceHost.Id, userConfiguration.Id, groupConfiguration.Id);
            await CreateMaintenanceMemberAsync(project.Id, user.Id);
            var part = await CrateDevicePartAsync(project.Id);
            var checkItem = await CreateCheckItemAsync(part.Id);
            var record = await CreateRecordAsync(part.Id);
            await CreateCheckedResult(record.Id, checkItem.Id);

            await CrateJCSiteTestDataAsync(groupConfiguration.Id, userConfiguration.Id);
        }

        private async Task CrateJCSiteTestDataAsync(Guid groupConfigurationId, Guid userConfigurationId)
        {
            var productionBase = await _productionBaseRepository.FindAsync(item => item.Id == 2560);

            if (productionBase == null)
            {
                productionBase = await _productionBaseRepository.InsertAsync(new ProductionBaseModel(2560, "JC基地"));
            }

            var workshop = await _productionWorkshopRepository.FindAsync(item => item.SiteId == productionBase.Id
            && item.WorkshopName == "JC2-1");

            if (workshop == null)
            {
                workshop = await _productionWorkshopRepository.InsertAsync(new ProductionWorkshopModel(
                    productionBase.Id,
                    "JC2-1"));
            }

            var process = await _productionProcessRepository.FindAsync(item => item.ProductionWorkshopId == workshop.Id
            && item.ProcessName == "搅拌工序");

            if (process == null)
            {
                process = await _productionProcessRepository.InsertAsync(new ProductionProcessModel(workshop.Id, "搅拌工序"));
            }

            var host = await _deviceHostRepository.FindAsync(item => item.ProductionProcessId == process.Id
            && item.DeviceHostName == "JC2-1阳极搅拌一期系统");

            if (host == null)
            {
                host = await _deviceHostRepository.InsertAsync(new DeviceHostModel(process.Id, "JC2-1阳极搅拌一期系统", "mixing"));
            }

            var device = await _deviceMaintenanceRepository.FindAsync(item => item.DeviceHostId == host.Id && item.DeviceName == "5#-MIXIX006");

            if (device == null)
            {
                device = await _deviceMaintenanceRepository.InsertAsync(new DeviceMaintenanceModel(host.Id, "5#-MIXIX006", groupConfigurationId, userConfigurationId, null!));
            }

            var mixing = await _devicePartRepository.FindAsync(item => item.DeviceMaintenanceId == device.Id && item.DevicePartName == "搅拌轴承");

            if (mixing == null)
            {
                mixing = await _devicePartRepository.InsertAsync(new DevicePartModel(
                    device.Id,
                    "搅拌轴承",
                    MaintenanceStatus.RUNING,
                    800,
                    1200,
                    1000));
            }

            var mixingCheck1 = await _devicePartCheckItemRepository.FindAsync(item => item.Description == "TestCheckItem1"
            && item.DevicePartId == mixing.Id);

            if (mixingCheck1 == null)
            {
                await _devicePartCheckItemRepository.InsertAsync(new DevicePartCheckItemModel(_guidGenerator.Create(), mixing.Id, "TestCheckItem1"));
            }

            var dis = await _devicePartRepository.FindAsync(item => item.DeviceMaintenanceId == device.Id && item.DevicePartName == "分散轴承");

            if (dis == null)
            {
                dis = await _devicePartRepository.InsertAsync(new DevicePartModel(
                    device.Id,
                    "分散轴承",
                    MaintenanceStatus.RUNING,
                    1100,
                    1200,
                    1000));
            }

            var disCheck1 = await _devicePartCheckItemRepository.FindAsync(item =>
                item.Description == "TestCheckItem1"
                && item.DevicePartId == mixing.Id);

            if (disCheck1 == null)
            {
                await _devicePartCheckItemRepository.InsertAsync(new DevicePartCheckItemModel(_guidGenerator.Create(), dis.Id, "TestCheckItem1"));
            }

            // 搅拌轴特征值
            {
                var currentLifetimeCharacteristicModel = await _devicePartCharacteristicRepository.FindAsync(item =>
                item.DevicePartId == mixing.Id
                && item.CharacteristicName == "当前寿命");

                if (currentLifetimeCharacteristicModel == null)
                {
                    currentLifetimeCharacteristicModel = await _devicePartCharacteristicRepository.InsertAsync(new DevicePartCharacteristicModel(mixing.Id, "当前寿命", "short", "M100"));
                }

                var AccumulatedDowntimeCharacteristicModel = await _devicePartCharacteristicRepository.FindAsync(item =>
                item.DevicePartId == mixing.Id
                && item.CharacteristicName == "停机寿命");

                if (AccumulatedDowntimeCharacteristicModel == null)
                {
                    AccumulatedDowntimeCharacteristicModel = await _devicePartCharacteristicRepository.InsertAsync(new DevicePartCharacteristicModel(mixing.Id, "停机寿命", "short", "M200"));
                }

                var EconomicLifetimeThresholdCharacteristicModel = await _devicePartCharacteristicRepository.FindAsync(item =>
                item.DevicePartId == mixing.Id
                && item.CharacteristicName == "经济寿命");

                if (EconomicLifetimeThresholdCharacteristicModel == null)
                {
                    EconomicLifetimeThresholdCharacteristicModel = await _devicePartCharacteristicRepository.InsertAsync(new DevicePartCharacteristicModel(mixing.Id, "经济寿命", "short", "M300"));
                }
            }

            // 分散轴特征值
            {
                var currentLifetimeCharacteristicModel = await _devicePartCharacteristicRepository.FindAsync(item =>
                item.DevicePartId == dis.Id
                && item.CharacteristicName == "当前寿命");

                if (currentLifetimeCharacteristicModel == null)
                {
                    currentLifetimeCharacteristicModel = await _devicePartCharacteristicRepository.InsertAsync(new DevicePartCharacteristicModel(dis.Id, "当前寿命", "short", "M100"));
                }

                var AccumulatedDowntimeCharacteristicModel = await _devicePartCharacteristicRepository.FindAsync(item =>
                item.DevicePartId == dis.Id
                && item.CharacteristicName == "停机寿命");

                if (AccumulatedDowntimeCharacteristicModel == null)
                {
                    AccumulatedDowntimeCharacteristicModel = await _devicePartCharacteristicRepository.InsertAsync(new DevicePartCharacteristicModel(dis.Id, "停机寿命", "short", "M200"));
                }

                var EconomicLifetimeThresholdCharacteristicModel = await _devicePartCharacteristicRepository.FindAsync(item =>
                item.DevicePartId == dis.Id
                && item.CharacteristicName == "经济寿命");

                if (EconomicLifetimeThresholdCharacteristicModel == null)
                {
                    EconomicLifetimeThresholdCharacteristicModel = await _devicePartCharacteristicRepository.InsertAsync(new DevicePartCharacteristicModel(dis.Id, "经济寿命", "short", "M300"));
                }
            }
        }

        private async Task<ProductionBaseModel> CrateProductionBaseAsync()
        {
            var productionBase = await _productionBaseRepository.FindAsync(item => item.Id == 9999);

            if (productionBase == null)
            {
                productionBase = await _productionBaseRepository.InsertAsync(new ProductionBaseModel(9999, "TestProductionBaseName"));
            }

            return productionBase;
        }

        private async Task<DeviceHostModel> CreateDeviceHostAsync(Guid processId)
        {
            var deviceHost = await _deviceHostRepository.FindAsync(item => item.DeviceHostName == "TestDeviceHostName");

            if (deviceHost == null)
            {
                deviceHost = await _deviceHostRepository.InsertAsync(new DeviceHostModel(processId, "TestDeviceHostName", string.Empty));
            }

            return deviceHost;
        }

        private async Task<ProductionProcessModel> CreateProductionProcessAsync(Guid productionWorkshopId)
        {
            var model = await _productionProcessRepository.FindAsync(item => item.ProcessName == "TestProcessName");

            if (model == null)
            {
                return await _productionProcessRepository.InsertAsync(new ProductionProcessModel(productionWorkshopId, "TestProcessName"));
            }

            return model;
        }


        private async Task<ProductionWorkshopModel> CreateProductionWorkshopAsync(int site)
        {
            var model = await _productionWorkshopRepository.FindAsync(item => item.WorkshopName == "TestWorkshopName");

            if (model == null)
            {
                model = await _productionWorkshopRepository.InsertAsync(new ProductionWorkshopModel(
                    site,
                    "TestWorkshopName"));
            }

            return model;
        }

        private async Task CreateMaintenanceMemberAsync(Guid projectId, string userId)
        {
            if (!await _maintenanceMemberRepository.AnyAsync(item => item.DeviceMaintenanceId == projectId && item.ComeUserId == userId))
            {
                await _maintenanceMemberRepository.InsertAsync(new MaintenanceMemberModel(_guidGenerator.Create(), projectId, userId));
            }
        }

        private async Task<ComeUserModel> CreateComeUserAsync()
        {
            var model = await _comeUserRepository.FindAsync(item => item.Id == "60218718");

            if (model == null)
            {
                return await _comeUserRepository.InsertAsync(new ComeUserModel("60218718", "lanxf01"));
            }

            return model;
        }

        private async Task<ComeGroupNotificationConfigurationModel> CreateComeGroupNotificationConfigurationAsync()
        {
            var model = await _comeGroupNotificationConfigurationRepository.FindAsync(item => item.GroupName == "TestGroupNotificationConfiguration");

            if (model == null)
            {
                return await _comeGroupNotificationConfigurationRepository.InsertAsync(new ComeGroupNotificationConfigurationModel(
              _guidGenerator.Create(),
              "1642112457",
              "303686603505665",
              "659JOPEldYL55Mi3sqb38H9Txd1q9EYw",
              "SECb38733e71346cb9353315eeef15d8f919c90d2d224d17bcb89cbe0c4cb9ccf42",
              "52046048273d0909e3f9025f4c46de0e601caea47539b56199055f0a45cc0cc7",
              "TestGroupNotificationConfiguration"));
            }

            return model;
        }

        private async Task<ComeUserNotificationConfigurationModel> CreateComeUserNotificationConfigurationAsync()
        {
            var model = await _comeUserNotificationConfigurationRepository.FindAsync(
                item => item.Name == "TestComeUserNotificationConfiguration");

            if (model == null)
            {
                return await _comeUserNotificationConfigurationRepository.InsertAsync(
                           new ComeUserNotificationConfigurationModel(
                               _guidGenerator.Create(),
                               "1642112457",
                               "303717003821057",
                               "659JOPEldYL55Mi3sqb38H9Txd1q9EYw",
                               "TestComeUserNotificationConfiguration"));
            }
            return model;
        }

        private async Task<DevicePartCheckedResultModel> CreateCheckedResult(Guid recordId, Guid checkItemId)
        {
            var model = await _devicePartCheckedResultRepository.FindAsync(item =>
                item.MaintenanceRecordId == recordId && item.CheckItemId == checkItemId);

            if (model != null)
            {
                return model;
            }

            return await _devicePartCheckedResultRepository.InsertAsync(new DevicePartCheckedResultModel(
                _guidGenerator.Create(),
                recordId,
                checkItemId,
                false));
        }

        private async Task<MaintenanceRecordModel> CreateRecordAsync(Guid partId)
        {
            var model = await _maintenanceRecordRepository.FindAsync(item => item.DevicePartId == partId);

            if (model != null)
            {
                return model;
            }

            return await _maintenanceRecordRepository.InsertAsync(new MaintenanceRecordModel(
                _guidGenerator.Create(),
                partId,
                MaintenanceStep.START,
                true,
                null));
        }

        private async Task<DevicePartCheckItemModel> CreateCheckItemAsync(Guid partId)
        {
            var model = await _devicePartCheckItemRepository.FindAsync(item => item.Description == "TestCheckItem1" && item.DevicePartId == partId);

            if (model == null)
            {
                return await _devicePartCheckItemRepository.InsertAsync(new DevicePartCheckItemModel(
                    _guidGenerator.Create(),
                    partId,
                    "TestCheckItem1"));
            }

            return model;
        }

        /// <summary>
        /// 创建部件
        /// </summary>
        private async Task<DevicePartModel> CrateDevicePartAsync(Guid projectId)
        {
            var model = await _devicePartRepository.FindAsync(item => item.DevicePartName == "TestDevicePartName"
            && item.DeviceMaintenanceId == projectId);

            if (model != null)
            {
                return model;
            }

            return await _devicePartRepository.InsertAsync(new DevicePartModel(
                projectId,
                "TestDevicePartName",
                MaintenanceStatus.UNDER_MAINTENANCE,
                1000,
                1200,
                1000));
        }

        /// <summary>
        /// 创建一个维护
        /// </summary>
        private async Task<DeviceMaintenanceModel> CreateProjectAsync(Guid deviceHostId, Guid userConfigurationId, Guid groupConfigurationId)
        {
            var model = await _deviceMaintenanceRepository.FindAsync(item => item.DeviceName == "TestDeviceName");

            if (model != null)
            {
                return model;
            }

            return await _deviceMaintenanceRepository.InsertAsync(
                new DeviceMaintenance.DeviceMaintenanceModel(
                    deviceHostId,
                    "TestDeviceName",
                    groupConfigurationId,
                    userConfigurationId, null!));
        }
    }
}
